﻿// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the LGPL License, Version 3.0. See License.txt in the project root for license information.
// Website: https://admin.blazor.zone

using BlazorAdmin.Models;
using BlazorAdmin.Interface;
using BootstrapBlazor.Components;
using BlazorAdmin.Web.Shared.Extensions;
using BlazorAdmin.Web.Shared.Models;
using BlazorAdmin.Web.Shared.Services;
using BlazorAdmin.Web.Shared.Utils;
using Microsoft.AspNetCore.Components;
using System.Diagnostics.CodeAnalysis;

namespace BlazorAdmin.Web.Shared.Pages.Admin
{
    /// <summary>
    /// 
    /// </summary>
    public partial class Menus
    {
        [Inject]
        [NotNull]
        private IBootstrapAdminService? AdminService { get; set; }

        [Inject]
        [NotNull]
        private DialogService? DialogService { get; set; }

        [Inject]
        [NotNull]
        private ToastService? ToastService { get; set; }

        [Inject]
        [NotNull]
        private IRole? RoleService { get; set; }

        [Inject]
        [NotNull]
        private INavigation? NavigationService { get; set; }

        [Inject]
        [NotNull]
        private IDict? DictService { get; set; }

        [Inject]
        [NotNull]
        private BootstrapAppContext? AppContext { get; set; }

        [Inject]
        [NotNull]
        private NavigationManager? NavigationManager { get; set; }

        [NotNull]
        private List<SelectedItem>? Targets { get; set; }

        [NotNull]
        private List<SelectedItem>? Apps { get; set; }

        [NotNull]
        private List<SelectedItem>? ParementMenus { get; set; }

        private ITableSearchModel? SearchModel { get; set; } = new MenusSearchModel();

        /// <summary>
        /// OnInitialized 方法
        /// </summary>
        protected override void OnInitialized()
        {
            base.OnInitialized();

            Targets = LookupHelper.GetTargets();
            Apps = DictService.GetApps().ToSelectedItemList();

            ParementMenus = NavigationService.GetAllMenus(AppContext.LoginName).Where(s => s.ParentID == 0).Select(s => new SelectedItem(s.ID.ToString(), s.Name)).ToList();
            ParementMenus.Insert(0, new SelectedItem("0", "请选择"));
        }

        private bool AuthorizeButton(string operate)
        {
            var url = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
            return AdminService.AuhorizingBlock(AppContext.LoginName, url, operate);
        }

        private async Task OnAssignmentRoles(Navigation menu)
        {
            List<SelectedItem> roles = RoleService.GetAll().ToSelectedItemList();
            List<int> values = RoleService.GetRolesByMenuId(menu.ID);

            await DialogService.ShowAssignmentDialog($"分配角色 - 当前菜单: {menu.Name}", roles, values, () =>
            {
                IEnumerable<int> ids = from u in roles where u.Active select int.Parse(u.Value);
                bool result = RoleService.SaveRolesByMenuId(menu.ID, ids);
                return Task.FromResult(result);
            }, ToastService);
        }

        private Task<QueryData<Navigation>> OnQueryAsync(QueryPageOptions options)
        {
            var navs = NavigationService.GetAllMenus(AppContext.LoginName);
            var menus = navs.Where(m => m.ParentID == 0);

            // 处理模糊查询
            if (options.Searchs.Any())
            {
                menus = menus.Where(options.Searchs.GetFilterFunc<Navigation>(FilterLogic.Or));
            }

            //  处理 Filter 高级搜索
            if (options.CustomerSearchs.Any() || options.Filters.Any())
            {
                menus = menus.Where(options.CustomerSearchs.Concat(options.Filters).GetFilterFunc<Navigation>());
            }

            foreach (var item in menus)
            {
                item.HasChildren = navs.Any(i => i.ParentID == item.ID);
            }

            return Task.FromResult(new QueryData<Navigation>()
            {
                IsFiltered = true,
                IsSearch = true,
                IsSorted = true,
                Items = menus
            });
        }

        private Task<IEnumerable<TableTreeNode<Navigation>>> OnTreeExpand(Navigation menu)
        {
            var navs = NavigationService.GetAllMenus(AppContext.LoginName);
            return Task.FromResult(navs.Where(m => m.ParentID == menu.ID).OrderBy(m => m.SortNo).AsEnumerable().Select(i => new TableTreeNode<Navigation>(i)));
        }

        private Task<IEnumerable<TableTreeNode<Navigation>>> TreeNodeConverter(IEnumerable<Navigation> items)
        {
            var ret = BuildTreeNodes(items, 0);
            return Task.FromResult(ret);

            IEnumerable<TableTreeNode<Navigation>> BuildTreeNodes(IEnumerable<Navigation> items, int parentId)
            {
                var navs = NavigationService.GetAllMenus(AppContext.LoginName);
                var ret = new List<TableTreeNode<Navigation>>();
                ret.AddRange(items.Where(i => i.ParentID == parentId).Select((nav, index) => new TableTreeNode<Navigation>(nav)
                {
                    HasChildren = navs.Any(i => i.ParentID == nav.ID),
                    IsExpand = navs.Any(i => i.ParentID == nav.ID),
                    Items = BuildTreeNodes(navs.Where(i => i.ParentID == nav.ID), nav.ID)
                }));
                return ret;
            }
        }

        private static bool ModelEqualityComparer(Navigation x, Navigation y) => x.ID == y.ID;
    }
}